# -*- coding:utf-8 -*-

__author__='zhaoxp'

from pprint import pprint

'''
使用super来初始化父类
总结一下，是为了解决多继承中的__init__执行问题
注意Python 3 对super做了更新，可以更方便的使用
'''


class MyBaseClass(object):
    def __init__(self,value):
        self.value = value
        print('MyBaseClass.__init__')


class MyChildClass(MyBaseClass):
    def __init__(self):
        MyBaseClass.__init__(self,5)
        print('MyChildClass.__init__')

##################################################################################

class TimesTwo(object):
    def __init__(self):
        self.value *= 2
        print('TimesTwo.__init__')


class PlusFive(object):
    def __init__(self):
        self.value += 5
        print('PlusFive.__init__')


class OneWay(MyBaseClass,TimesTwo,PlusFive):
    def __init__(self,value):
        MyBaseClass.__init__(self,value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)
        print('OneWay.__init__')


class AnotherWay(MyBaseClass,PlusFive,TimesTwo):
    def __init__(self,value):
        MyBaseClass.__init__(self,value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)
        print('AnotherWay.__init__')

##################################################################################

class TimesFive(MyBaseClass):
    def __init__(self,value):
        MyBaseClass.__init__(self,value)
        self.value *= 5
        print('TimesFive.__init__')


class PlusTwo(MyBaseClass):
    def __init__(self,value):
        MyBaseClass.__init__(self,value)
        self.value += 2
        print('PlusTwo.__init__')


class ThisWay(TimesFive,PlusTwo):
    def __init__(self,value):
        TimesFive.__init__(self,value)
        PlusTwo.__init__(self,value)
        print('ThisWay.__init__')

##################################################################################

class TimesFiveCorrect(MyBaseClass):
    def __init__(self,value):
        super(TimesFiveCorrect,self).__init__(value)
        self.value *= 5
        print('TimesFiveCorrect.__init__')


class PlusTwoCorrect(MyBaseClass):
    def __init__(self,value):
        super(PlusTwoCorrect,self).__init__(value)
        self.value += 2
        print('PlusTwoCorrect.__init__')


class GoodWay(TimesFiveCorrect,PlusTwoCorrect):
    def __init__(self,value):
        super(GoodWay,self).__init__(value)
        print('GoodWay.__init__')        


class GoodWay2(PlusTwoCorrect,TimesFiveCorrect):
    def __init__(self,value):
        super(GoodWay2,self).__init__(value)
        print('GoodWay2.__init__')        


'''
# following is for Python version 3.*
class Explicit(MyBaseClass):
    def __init__(self,value):
        super(__class__,self).__init__(value+5)


class Implicit(MyBaseClass):
    def __init__(self,value):
        super().__init__(value*2)

'''

if __name__=='__main__':
    print('show how and why to use super')
    foo = OneWay(5)
    print('OneWay foo.value = %s'%foo.value)
    print('-'*10)
    bar = AnotherWay(5)
    print('AnotherWay bar.value = %s'%bar.value)
    print('-'*10)
    f = ThisWay(5)
    print("ThisWay, should be (5*5)+2 = 27, and actually f.value = %s"%f.value)
    print('The reason is that MyBaseClass.__init__ was called twice')
    print('-'*10)
    b1 = GoodWay(5)
    print('GoodWay,  should be 5*(5+2) = 35, and actually b1.value = %s'%b1.value)
    print('-'*10)
    b2 = GoodWay2(5)
    print('GoodWay2, should be 5*5+2   = 27, and actually b2.value = %s'%b2.value)
    print('-'*10)
    pprint(GoodWay.mro())
    print('-'*10)
    pprint(GoodWay2.mro())